<template>
    <lemon-common uri="role" ref="commonRef" :search-form-model="searchFormModel" :search-form-item="searchFormItem" :search-condition="searchCondition" :table-item="tableItem" :dialog-info-form-model="dialogInfoFormModel" :dialog-info-form-item="dialogInfoFormItem" :dialog-edit-form-model="dialogEditFormModel" :dialog-edit-form-item="dialogEditFormItem" :dialog-add-form-model="dialogAddFormModel" :dialog-add-form-item="dialogAddFormItem">
        <template #tableFrontBtn="scope">
            <el-button type="primary" size="default" @click="onUser(scope.row)" v-has-permission="'FINDUSER'">用户</el-button>
            <el-button type="success" size="default" @click="onMenuResource(scope.row)" v-has-permission="'FINDMENURESOURCE'">资源</el-button>
        </template>
    </lemon-common>

    <!-- 用户列表弹窗 -->
    <lemon-dialog v-model="userDialogShow" dialog-width="70%" dialog-title="用户列表" @on-cancel="onUserDialogCancel" @on-before-close="onUserDialogCancel">
        <el-table :data="userList" :border="true" style="width: 100%" max-height="60vh">
            <el-table-column prop="username" label="用户名" min-width="150" show-overflow-tooltip />
            <el-table-column prop="name" label="姓名" min-width="150" show-overflow-tooltip />
            <el-table-column prop="phone" label="手机号" min-width="150" show-overflow-tooltip />
            <el-table-column prop="sex" label="性别" min-width="80" show-overflow-tooltip :formatter="genderFormat" />
            <el-table-column prop="email" label="邮箱" min-width="200" show-overflow-tooltip />
            <el-table-column prop="birthday" label="生日" min-width="150" show-overflow-tooltip />
            <el-table-column prop="address" label="地址" min-width="200" show-overflow-tooltip :formatter="addressFormat" />
            <el-table-column prop="createTime" label="创建时间" min-width="200" show-overflow-tooltip />
            <el-table-column prop="status" label="状态" min-width="100" show-overflow-tooltip :formatter="statusFormat" />
        </el-table>
    </lemon-dialog>

    <!-- 菜单资源列表弹窗 -->
    <lemon-dialog v-model="menuResourceDialogShow" dialog-width="70%" :dialog-footer="hasPermission('UPDATEMENURESOURCE')" dialog-title="菜单资源列表" @on-submit="onMenuResourceSubmit" @on-cancel="onMenuResourceDialogCancel" @on-before-close="onMenuResourceDialogCancel">
        <el-table :data="menuResourceList" :border="true" style="width: 100%" max-height="60vh" :tree-props="treeProps" row-key="menuId" default-expand-all @select-all="onSelectAll">
            <el-table-column type="selection" width="55">
                <template #default="scope">
                    <el-checkbox v-model="scope.row['selected']" size="large" @change="onMenuSelect(scope.row.menuId, scope.row['selected'])" />
                </template>
            </el-table-column>
            <el-table-column label="菜单名称" width="200">
                <template #default="scope">
                    <lemon-icon size="20" :icon="scope?.row?.menuIcon" style="padding-right: 5px; top: 4px" :value="scope?.row?.menuName" />
                </template>
            </el-table-column>
            <el-table-column label="资源接口">
                <template #default="scope">
                    <template v-for="opt in scope.row.resourceList">
                        <el-checkbox v-model="opt['selected']" :label="opt.name" size="default" @change="onResoueceSelect(scope.row.menuId, opt.path, opt['selected'])" :style="{ 'pointer-events': hasPermission('UPDATEMENURESOURCE') ? 'auto' : 'none' }" />
                    </template>
                </template>
            </el-table-column>
        </el-table>
    </lemon-dialog>
</template>

<script setup lang="ts">
import { reactive, inject, ref } from "vue";
import { getNameById } from "@/utils/city";
import { genderFormat, statusFormat, statusOptions, hasPermission } from "@/utils/common";

//获取自定义全局方法
const { rule, http, emitter } = inject<any>("method");

//公共组件ref
const commonRef: any = ref(null);

//搜索的form
const searchFormModel = reactive({
    name: "",
    status: null,
});

//搜索form子项
const searchFormItem = reactive({
    name: { label: "名称", type: "input" },
    status: { label: "状态", type: "select", options: statusOptions },
});

//搜索的条件
const searchCondition = reactive({
    name: "like", //名称模糊查询
});

//表格每一项
const tableItem = reactive([
    { prop: "name", label: "名称", minWidth: "150" },
    { prop: "roleKey", label: "权限字符", minWidth: "150" },
    { prop: "description", label: "描述", minWidth: "300" },
    { prop: "createBy", label: "创建人", minWidth: "150" },
    { prop: "createTime", label: "创建时间", minWidth: "200" },
    { prop: "updateBy", label: "修改人", minWidth: "150" },
    { prop: "updateTime", label: "修改时间", minWidth: "200" },
    { prop: "status", label: "状态", minWidth: "100", formatter: statusFormat },
]);

//弹出框详情form
const dialogInfoFormModel = reactive({
    name: "",
    roleKey: "",
    description: "",
    createBy: "",
    createTime: null,
    updateBy: "",
    updateTime: null,
    status: null,
});

//弹出框详情form子项
const dialogInfoFormItem = reactive({
    name: { label: "名称", type: "input", readonly: true },
    roleKey: { label: "权限字符", type: "input", readonly: true },
    description: { label: "描述", type: "textarea", rows: 3, readonly: true },
    createBy: { label: "创建人", type: "input", readonly: true },
    createTime: { label: "创建时间", type: "datetime", readonly: true },
    updateBy: { label: "修改人", type: "input", readonly: true },
    updateTime: { label: "修改时间", type: "datetime", readonly: true },
    status: { label: "状态", type: "switch", inlinePrompt: true, activeText: "启用", activeValue: 1, inactiveText: "停用", inactiveValue: 0, readonly: true },
});

//弹出框编辑form
const dialogEditFormModel = reactive({
    id: null,
    name: "",
    roleKey: "",
    description: "",
});

//弹出框编辑form子项
const dialogEditFormItem = reactive({
    name: { label: "名称", type: "input", rules: rule.require.input("名称") },
    roleKey: { label: "权限字符", type: "input", rules: [...rule.require.input("权限字符"), ...rule.leng(5, 10)] },
    description: { label: "描述", type: "textarea", rows: 3 },
});

//弹出框编辑form
const dialogAddFormModel = reactive({
    name: "",
    roleKey: "",
    description: "",
});

//弹出框编辑form子项
const dialogAddFormItem = reactive({
    name: { label: "名称", type: "input", rules: rule.require.input("名称") },
    roleKey: { label: "权限字符", type: "input", rules: [...rule.require.input("权限字符"), ...rule.leng(5, 20)] },
    description: { label: "描述", type: "textarea", rows: 3 },
});

//用户详情弹窗
const userDialogShow = ref<boolean>(false);

//用户列表
const userList = ref<any[]>([]);
//根据角色ID 获取用户列表
const onUser = async (row: any) => {
    userList.value = await http.get(`/role/findUser/${row.id}`);
    userDialogShow.value = true;
};

//弹窗关闭
const onUserDialogCancel = () => {
    userDialogShow.value = false;
};

//地址格式化
const addressFormat = (row: any, column: any) => {
    let value = "";
    if (row?.provinceId) {
        value += getNameById(row.provinceId) + " ";
    }
    if (row?.cityId) {
        value += getNameById(row.cityId) + " ";
    }
    if (row?.countyId) {
        value += getNameById(row.countyId) + " ";
    }
    return value + row[column.property];
};

//菜单资源dialog显示
const menuResourceDialogShow = ref(false);

//树形结构属性
const treeProps = reactive({ children: "children", hasChildren: "hasChildren", checkStrictly: false });

//选择的角色
const selectRoleId = ref();

// 菜单资源列表数据
const menuResourceList = ref<any[]>([]);

// 初始化原始列表数据
const initializationList = ref<any[]>([]);

// 菜单资源点击事件
const onMenuResource = async (row: any) => {
    menuResourceList.value = await http.get(`role/findMenuResource/${row.id}`);
    initializationList.value = JSON.parse(JSON.stringify(menuResourceList.value)); // 深拷贝初始数据
    selectRoleId.value = row.id;
    menuResourceDialogShow.value = true;
};

//全选
const onSelectAll = (selection: any[]) => {
    const allSelected = selection.length > 0;
    const update = (data: any[]) => {
        data.forEach((item: any) => {
            item.selected = allSelected;
            if (item.resourceList) {
                item.resourceList.forEach((item: any) => (item.selected = allSelected));
            }
            if (item.children) {
                update(item.children);
            }
        });
    };
    update(menuResourceList.value);
};

// 菜单选中事件
const onMenuSelect = (menuId: string, selected: boolean) => {
    const parentIdList: string[] = [];
    const update = (data: any[]) => {
        data.forEach((item: any) => {
            if (item.menuId == menuId) {
                parentIdList.push(...item.treeLinkId.split(",").slice(1, -1));
                item.selected = selected;
                if (item.resourceList) {
                    item.resourceList.forEach((item: any) => (item.selected = selected));
                }
                //全选子菜单
                const updateChild = (childData: any[]) => {
                    childData.forEach((child: any) => {
                        child.selected = selected;
                        if (child.resourceList) {
                            child.resourceList.forEach((c: any) => (c.selected = selected));
                        }
                        if (child.children && child.children.length > 0) {
                            updateChild(child.children);
                        }
                    });
                };
                if (item.children && item.children.length > 0) {
                    updateChild(item.children);
                }
            }
            if (item.children && item.children.length > 0) {
                update(item.children);
            }
        });
    };
    update(menuResourceList.value);

    // 更新父级菜单
    const updateParent = (parentData: any[]) => {
        parentData.forEach((item) => {
            if (parentIdList.includes(item.menuId)) {
                item.selected = item.children.some((child: any) => child.selected);
            }
            if (item.children && item.children.length > 0) {
                updateParent(item.children);
            }
        });
    };
    updateParent(menuResourceList.value);
};

// 处理资源复选框变化
const onResoueceSelect = (menuId: string, resourcePath: string, selected: boolean) => {
    const update = (data: any[]) => {
        data.forEach((item) => {
            if (item.menuId === menuId) {
                item.resourceList.forEach((resource: any) => {
                    if (resource.path == resourcePath) {
                        resource.selected = selected;
                        //是否勾选菜单
                        if (resource.selected) {
                            item.selected = true;
                        } else {
                            item.selected = item.resourceList.some((resource: any) => resource.selected);
                        }
                        //勾选父菜单
                        const linkIdList = item.treeLinkId.split(",").slice(1, -1);
                        if (linkIdList && linkIdList.length > 0) {
                            const updateParent = (parentData: any[]) => {
                                parentData.forEach((pi) => {
                                    if (linkIdList.includes(pi.menuId)) {
                                        pi.selected = pi.children.some((child: any) => child.selected);
                                    }
                                    if (pi.children && pi.children.length > 0) {
                                        updateParent(pi.children);
                                    }
                                });
                            };
                            updateParent(menuResourceList.value);
                        }
                    }
                });
            }
            if (item.children && item.children.length > 0) {
                update(item.children);
            }
        });
    };
    update(menuResourceList.value);
};

const onMenuResourceSubmit = async () => {
    const param = getChangedData();
    if (param && param.length > 0) {
        const data = await http.put("role/updateMenuResource", param);
        if (data?.success) {
            emitter.emit("msg-success", data?.data);
            onMenuResourceDialogCancel();
        }
    } else {
        emitter.emit("msg-warning", "没有数据需要更新");
    }
};

//菜单资源dialog取消
const onMenuResourceDialogCancel = () => {
    menuResourceDialogShow.value = false;
    menuResourceList.value = [];
    initializationList.value = [];
};

// 获取变化的数据
const getChangedData = (): any[] => {
    const changedData: any[] = [];

    const getChange = (currentData: any[], originalData: any[]) =>
        currentData?.forEach((item: any) => {
            //菜单数据
            const menuData = originalData.find((originalItem: any) => originalItem.menuId === item.menuId);
            if (menuData.selected !== item.selected) {
                changedData.push({
                    roleId: selectRoleId.value,
                    menuId: item.menuId,
                    resourcePath: null,
                    selected: item.selected,
                });
            }
            //资源数据
            if (item.resourceList && item.resourceList.length > 0) {
                item.resourceList.forEach((resource: any) => {
                    const resourceData = menuData.resourceList.find((originalItem: any) => originalItem.path === resource.path);
                    if (resourceData.selected !== resource.selected) {
                        changedData.push({
                            roleId: selectRoleId.value,
                            menuId: item.menuId,
                            resourcePath: resource.path,
                            selected: resource.selected,
                        });
                    }
                });
            }
            //子菜单数据
            if (menuData.children) {
                getChange(item.children, menuData.children);
            }
        });
    getChange(menuResourceList.value, initializationList.value);
    return changedData;
};
</script>

<style scoped lang="less"></style>
